#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import sys
import subprocess
import platform
import shutil
from PIL import Image
import argparse
import time

def install_requirements():
    """安装依赖包"""
    print("正在安装依赖...")
    subprocess.check_call([sys.executable, "-m", "pip", "install", "-r", "requirements.txt"])
    # 安装PyInstaller和Pillow
    subprocess.check_call([sys.executable, "-m", "pip", "install", "PyInstaller", "Pillow"])

def create_windows_icon():
    """创建Windows图标文件"""
    try:
        print("正在创建Windows图标...")
        # 检查是否有现有图标
        if os.path.exists('icon.jpg'):
            # 使用现有图像
            try:
                img = Image.open('icon.jpg')
            except Exception as e:
                print(f"无法打开icon.jpg: {str(e)}")
                # 创建基础图像（256x256），蓝色
                img = Image.new('RGB', (256, 256), color='#2196F3')
        else:
            # 创建基础图像（256x256），蓝色
            img = Image.new('RGB', (256, 256), color='#2196F3')
        
        # 保存为ICO格式
        img.save('app.ico', format='ICO', sizes=[(16, 16), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)])
        
        # 验证文件是否创建成功
        if not os.path.exists('app.ico'):
            raise Exception("Windows图标文件创建失败")
            
        print("Windows图标文件已创建：app.ico")
        return True
        
    except Exception as e:
        print(f"创建Windows图标文件时出错: {str(e)}")
        # 创建一个空的图标文件以允许构建继续
        try:
            with open('app.ico', 'wb') as f:
                f.write(b'ico')
            print("已创建空图标文件")
            return True
        except:
            print("无法创建空图标文件")
            return False

def create_icns():
    """创建macOS图标文件"""
    try:
        # 创建临时目录
        if not os.path.exists('icon.iconset'):
            os.makedirs('icon.iconset')
        
        # 检查是否有现有图标
        if os.path.exists('icon.jpg'):
            # 使用现有图像
            try:
                img = Image.open('icon.jpg')
                # 确保图像是正方形的
                width, height = img.size
                size = min(width, height)
                left = (width - size) // 2
                top = (height - size) // 2
                right = left + size
                bottom = top + size
                img = img.crop((left, top, right, bottom))
                img = img.resize((1024, 1024), Image.Resampling.LANCZOS)
                img.save('icon_1024.png')
            except Exception as e:
                print(f"无法处理icon.jpg: {str(e)}")
                # 创建基础图像（1024x1024），蓝色
                img = Image.new('RGB', (1024, 1024), color='#2196F3')
                img.save('icon_1024.png')
        else:
            # 创建基础图像（1024x1024），蓝色
            img = Image.new('RGB', (1024, 1024), color='#2196F3')
            img.save('icon_1024.png')
        
        # 创建不同尺寸的图标
        sizes = [16, 32, 64, 128, 256, 512, 1024]
        for size in sizes:
            img_size = (size, size)
            resized = Image.open('icon_1024.png')
            resized.thumbnail(img_size, Image.Resampling.LANCZOS)
            
            # 保存普通尺寸
            resized.save(f'icon.iconset/icon_{size}x{size}.png')
            # 保存@2x尺寸
            if size * 2 <= 1024:
                resized = Image.open('icon_1024.png')
                resized.thumbnail((size * 2, size * 2), Image.Resampling.LANCZOS)
                resized.save(f'icon.iconset/icon_{size}x{size}@2x.png')
        
        # 使用iconutil创建.icns文件
        result = subprocess.run(['iconutil', '-c', 'icns', 'icon.iconset'], 
                              capture_output=True, text=True)
        
        if result.returncode != 0:
            raise Exception(f"iconutil失败: {result.stderr}")
            
        # 重命名生成的图标文件
        if os.path.exists('icon.icns'):
            if os.path.exists('app.icns'):
                os.remove('app.icns')
            os.rename('icon.icns', 'app.icns')
        
        # 清理临时文件
        subprocess.run(['rm', '-rf', 'icon.iconset'])
        os.remove('icon_1024.png')
        
        # 验证文件是否创建成功
        if not os.path.exists('app.icns'):
            raise Exception("图标文件创建失败")
            
        print("图标文件已创建：app.icns")
        return True
        
    except Exception as e:
        print(f"创建图标文件时出错: {str(e)}")
        # 清理可能存在的临时文件
        if os.path.exists('icon.iconset'):
            subprocess.run(['rm', '-rf', 'icon.iconset'])
        if os.path.exists('icon_1024.png'):
            os.remove('icon_1024.png')
        if os.path.exists('icon.icns'):
            os.remove('icon.icns')
        return False

def create_icons():
    """创建应用图标"""
    if platform.system() == "Darwin":
        print("正在创建macOS图标...")
        if not create_icns():
            print("将使用默认图标继续构建...")
            # 创建一个空的图标文件以允许构建继续
            with open('app.icns', 'wb') as f:
                f.write(b'icns')
    else:
        # 创建Windows图标
        create_windows_icon()

def parse_args():
    """解析命令行参数"""
    parser = argparse.ArgumentParser(description="构建工具")
    parser.add_argument('--clean', action='store_true', help='清理构建目录')
    return parser.parse_args()

def download_chromium():
    """下载Chromium浏览器到临时目录"""
    print("正在准备Chromium浏览器...")
    
    # 创建目标目录
    browser_dir = os.path.join("dist", "browser")
    if not os.path.exists(browser_dir):
        os.makedirs(browser_dir)
    
    # 首先检查是否有chrome-plugin目录中的Chrome
    chrome_plugin_dir = os.path.join(os.getcwd(), "chrome-plugin")
    if os.path.exists(chrome_plugin_dir) and os.path.isdir(chrome_plugin_dir):
        print(f"检测到chrome-plugin目录: {chrome_plugin_dir}")
        
        # 在chrome-plugin目录中查找chrome.exe
        chrome_exes = []
        for root, dirs, files in os.walk(chrome_plugin_dir):
            for file in files:
                if file.lower() == "chrome.exe":
                    chrome_exes.append(os.path.join(root, file))
        
        if chrome_exes:
            # 创建dist目录下的chrome-plugin目录
            dist_chrome_plugin = os.path.join("dist", "chrome-plugin")
            if os.path.exists(dist_chrome_plugin):
                shutil.rmtree(dist_chrome_plugin)
            
            print(f"在chrome-plugin中找到Chrome: {chrome_exes[0]}")
            
            # 复制整个chrome-plugin目录到dist目录
            print(f"正在复制chrome-plugin目录到: {dist_chrome_plugin}")
            shutil.copytree(chrome_plugin_dir, dist_chrome_plugin)
            
            print("chrome-plugin目录复制完成")
            return True
    
    # 检查是否有用户手动放置的chrome-win文件夹
    user_chrome_dir = os.path.join(os.getcwd(), "chrome-win")
    if os.path.exists(user_chrome_dir) and os.path.isdir(user_chrome_dir):
        user_chrome_exe = os.path.join(user_chrome_dir, "chrome.exe")
        if os.path.exists(user_chrome_exe) and os.path.isfile(user_chrome_exe):
            print(f"检测到用户手动放置的Chromium浏览器: {user_chrome_dir}")
            
            # 创建dist目录下的chrome-win文件夹
            dist_chrome_dir = os.path.join("dist", "chrome-win")
            if os.path.exists(dist_chrome_dir):
                shutil.rmtree(dist_chrome_dir)
            
            # 复制整个chrome-win文件夹到dist目录
            print(f"正在复制用户提供的浏览器到: {dist_chrome_dir}")
            shutil.copytree(user_chrome_dir, dist_chrome_dir)
            
            print("用户提供的Chromium浏览器复制完成")
            return True
    
    try:
        # 使用playwright工具下载浏览器
        subprocess.check_call([sys.executable, "-m", "playwright", "install", "chromium"])
        print("Chromium浏览器下载成功")
        
        # 直接使用默认路径，避免使用命令行获取
        print("查找Chromium浏览器路径...")
        home_dir = os.path.expanduser("~")
        
        # 根据操作系统确定浏览器路径模式
        if platform.system() == "Windows":
            chromium_pattern = os.path.join(home_dir, "AppData", "Local", "ms-playwright", "chromium-*", "chrome.exe")
        elif platform.system() == "Darwin":  # macOS
            chromium_pattern = os.path.join(home_dir, "Library", "Caches", "ms-playwright", "chromium-*", "chrome")
        else:  # Linux
            chromium_pattern = os.path.join(home_dir, ".cache", "ms-playwright", "chromium-*", "chrome")
        
        # 使用glob找到匹配的文件
        import glob
        matches = glob.glob(chromium_pattern)
        
        if not matches:
            print("未找到Chromium浏览器，尝试使用其他可能的路径...")
            
            # 尝试其他可能的路径
            if platform.system() == "Windows":
                # 尝试Program Files路径
                alt_patterns = [
                    os.path.join(os.environ.get("PROGRAMFILES", "C:\\Program Files"), "ms-playwright", "chromium-*", "chrome.exe"),
                    os.path.join(os.environ.get("PROGRAMFILES(X86)", "C:\\Program Files (x86)"), "ms-playwright", "chromium-*", "chrome.exe"),
                    os.path.join(os.getcwd(), ".playwright", "chromium-*", "chrome.exe")
                ]
            elif platform.system() == "Darwin":
                alt_patterns = [
                    "/Applications/ms-playwright/chromium-*/chrome",
                    os.path.join(os.getcwd(), ".playwright", "chromium-*", "chrome")
                ]
            else:
                alt_patterns = [
                    "/usr/local/ms-playwright/chromium-*/chrome",
                    "/opt/ms-playwright/chromium-*/chrome",
                    os.path.join(os.getcwd(), ".playwright", "chromium-*", "chrome")
                ]
            
            # 尝试所有备用路径
            for pattern in alt_patterns:
                alt_matches = glob.glob(pattern)
                if alt_matches:
                    matches = alt_matches
                    break
        
        if not matches:
            print("警告: 无法找到已安装的Chromium浏览器，将尝试手动下载")
            # 手动下载独立Chromium
            try:
                if platform.system() == "Windows":
                    # 使用curl或wget下载
                    chrome_download_url = "https://storage.googleapis.com/chromium-browser-snapshots/Win_x64/1097615/chrome-win.zip"
                    zip_path = os.path.join(os.getcwd(), "chrome-win.zip")
                    print(f"正在下载Chromium: {chrome_download_url}")
                    
                    import urllib.request
                    urllib.request.urlretrieve(chrome_download_url, zip_path)
                    
                    # 解压缩
                    import zipfile
                    with zipfile.ZipFile(zip_path, 'r') as zip_ref:
                        extract_dir = os.path.join(os.getcwd(), "chrome-win")
                        zip_ref.extractall(extract_dir)
                    
                    # 设置路径
                    matches = [os.path.join(extract_dir, "chrome-win", "chrome.exe")]
                    
                    # 清理下载的zip
                    os.remove(zip_path)
                else:
                    print("不支持在当前平台上手动下载Chromium")
                    return False
            except Exception as e:
                print(f"手动下载Chromium失败: {e}")
                return False
        
        if not matches:
            print("错误: 无法找到Chromium浏览器，构建失败")
            return False
        
        # 使用找到的第一个匹配
        chromium_path = matches[0]
        
        # 复制浏览器到目标目录
        print(f"找到Chromium浏览器: {chromium_path}")
        
        # 获取浏览器目录
        browser_executable = chromium_path
        browser_dir_src = os.path.dirname(browser_executable)
        
        # 复制整个浏览器目录
        print(f"正在复制浏览器文件从 {browser_dir_src} 到 {browser_dir}...")
        
        # 复制Chrome可执行文件
        chrome_exe = "chrome.exe" if platform.system() == "Windows" else "chrome"
        target_chrome = os.path.join(browser_dir, chrome_exe)
        shutil.copy2(browser_executable, target_chrome)
        
        # 复制必要的DLL和资源文件
        if platform.system() == "Windows":
            # 复制Windows上的必要文件
            for file in os.listdir(browser_dir_src):
                if file.endswith(".dll") or file.endswith(".bin") or file.endswith(".pak") or file.endswith(".dat"):
                    src_file = os.path.join(browser_dir_src, file)
                    dst_file = os.path.join(browser_dir, file)
                    if os.path.isfile(src_file):
                        shutil.copy2(src_file, dst_file)
            
            # 复制特定目录
            for dirname in ["locales"]:
                src_dir = os.path.join(browser_dir_src, dirname)
                dst_dir = os.path.join(browser_dir, dirname)
                if os.path.exists(src_dir) and os.path.isdir(src_dir):
                    if os.path.exists(dst_dir):
                        shutil.rmtree(dst_dir)
                    shutil.copytree(src_dir, dst_dir)
        else:
            # 在macOS和Linux上，尝试复制所有内容
            for item in os.listdir(browser_dir_src):
                src_item = os.path.join(browser_dir_src, item)
                dst_item = os.path.join(browser_dir, item)
                try:
                    if os.path.isdir(src_item):
                        if os.path.exists(dst_item):
                            shutil.rmtree(dst_item)
                        shutil.copytree(src_item, dst_item)
                    else:
                        shutil.copy2(src_item, dst_item)
                except (shutil.Error, OSError) as e:
                    print(f"警告: 复制 {src_item} 时出错: {e}")
        
        print("Chromium浏览器文件复制完成")
        return True
    except Exception as e:
        print(f"下载或复制Chromium浏览器时出错: {e}")
        import traceback
        print(traceback.format_exc())
        return False

def main():
    """主函数"""
    args = parse_args()
    
    # 清理构建目录
    if args.clean:
        print("正在清理构建目录...")
        if os.path.exists("build"):
            shutil.rmtree("build")
        if os.path.exists("dist"):
            shutil.rmtree("dist")
        print("构建目录已清理")
    
    # 获取系统信息
    system = platform.system()
    print(f"操作系统: {system}")
    
    # 检查并创建必要的目录
    print("正在检查必要的目录...")
    required_dirs = ["cache", "data", "config"]
    for dir_name in required_dirs:
        if not os.path.exists(dir_name):
            print(f"创建缺失的目录: {dir_name}")
            os.makedirs(dir_name)
    
    # 创建图标
    print("正在创建应用图标...")
    create_icons()
    
    # 确保图标文件存在
    if platform.system() == "Darwin" and not os.path.exists('app.icns'):
        print("警告：找不到图标文件，将创建空图标文件...")
        with open('app.icns', 'wb') as f:
            f.write(b'icns')
    elif platform.system() == "Windows" and not os.path.exists('app.ico'):
        print("警告：找不到图标文件，将创建空图标文件...")
        with open('app.ico', 'wb') as f:
            f.write(b'ico')
    
    # 打包应用
    print("正在构建应用程序...")
    spec_file = "tools_pc_v3.spec"
    subprocess.check_call([sys.executable, "-m", "PyInstaller", spec_file, "--noconfirm"])
    print("应用程序构建完成")
    
    # 下载和打包Chromium浏览器
    print("正在下载和打包Chromium浏览器...")
    success = download_chromium()
    if not success:
        print("错误: 下载Chromium浏览器失败，无法继续构建")
        print("应用程序需要本地浏览器才能正常工作")
        sys.exit(1)
    
    # 获取dist目录
    dist_dir = "dist"
    
    # 清理图标文件
    if os.path.exists('app.icns'):
        os.remove('app.icns')
    if os.path.exists('app.ico'):
        os.remove('app.ico')
    
    print(f"\n构建完成！")
    if platform.system() == "Windows":
        print("Windows用户可以直接运行dist目录下的exe文件")
    elif platform.system() == "Darwin":
        app_path = os.path.join(dist_dir, "AI直播助手.app")
        if os.path.exists(app_path):
            print(f"macOS应用程序已创建: {app_path}")
            print("你可以：")
            print("1. 直接运行这个应用程序")
            print("2. 将它拖到Applications文件夹中安装")
            
            # 创建dmg
            try:
                print("\n正在创建DMG安装包...")
                dmg_name = "AI直播助手.dmg"
                subprocess.call([
                    "hdiutil",
                    "create",
                    "-volname", "AI直播助手",
                    "-srcfolder", app_path,
                    "-ov",
                    "-format", "UDZO",
                    os.path.join(dist_dir, dmg_name)
                ])
                print(f"DMG安装包已创建: {os.path.join(dist_dir, dmg_name)}")
            except Exception as e:
                print(f"创建DMG失败: {str(e)}")
        else:
            print("警告：应用程序打包似乎失败了")
    else:
        print("Linux用户可以直接运行dist目录下的可执行文件")

if __name__ == "__main__":
    try:
        install_requirements()
        main()
    except Exception as e:
        print(f"构建过程中出错: {str(e)}")
        sys.exit(1) 